#include "plotter.h"

#include <QtGui>

#include "qwt_plot.h"
#include "qwt_plot_curve.h"
#include "qwt_plot_grid.h"
#include "qwt_plot_zoomer.h"
#include "qwt_text.h"
#include "qwt_symbol.h"
#include "qwt_plot_renderer.h"

Plotter::Plotter(QWidget* parent) : QWidget(parent)
{
    engine = new QwtPlot(this);
    engine->setAutoReplot(true);
    engine->setCanvasLineWidth(1);
    engine->setCanvasBackground(QColor("white"));
    engine->setFont(QFont("Sans Serif", 12, QFont::Bold, false));
    engine->setAxisFont(QwtPlot::xBottom, QFont("Sans Serif", 12, QFont::Normal, false));
    engine->setAxisFont(QwtPlot::yLeft,   QFont("Sans Serif", 12, QFont::Normal, false));

    QwtText xTitle("x"), yTitle("y");
    xTitle.setFont(QFont("Sans Serif", 14, QFont::Bold, false));
    yTitle.setFont(QFont("Sans Serif", 14, QFont::Bold, false));
    engine->setAxisTitle(QwtPlot::xBottom, xTitle);
    engine->setAxisTitle(QwtPlot::yLeft,   yTitle);

    grid = new QwtPlotGrid();
    grid->enableXMin(true);
    grid->enableYMin(true);
    grid->setMajPen(QPen(QBrush(QColor("grey")), 1, Qt::DashLine));
    grid->setMinPen(QPen(QBrush(QColor("grey")), 1, Qt::DotLine));
    grid->attach(engine);

    lineCurve = new QwtPlotCurve();
    lineCurve->setStyle(QwtPlotCurve::Lines);
    lineCurve->setPen(QPen(QBrush(QColor("red")), 1));
    lineCurve->attach(engine);

    dataCurve = new QwtPlotCurve();
    dataCurve->setStyle(QwtPlotCurve::Dots);
    dataCurve->setSymbol(new QwtSymbol(QwtSymbol::Cross, QBrush(QColor("green")), QPen(QBrush(QColor("green")), 1), QSize(3, 3)));
    dataCurve->attach(engine);

    engine->replot();

    zoomer = new QwtPlotZoomer(engine->canvas(), true);
    zoomer->setEnabled(false);

    QGridLayout* layout = new QGridLayout(this);
    layout->addWidget(engine, 0, 0);
}

Plotter::~Plotter()
{
    grid->detach();
    lineCurve->detach();
    dataCurve->detach();

    delete grid;
    delete lineCurve;
    delete dataCurve;
}

bool Plotter::isZoomingEnabled() const
{
    return zoomer->isEnabled();
}

void Plotter::setZoomingEnabled(bool enable)
{
    zoomer->setEnabled(enable);

    if(enable)
    {
        zoomer->setZoomBase(true);
    }
    else
    {
        engine->setAxisAutoScale(QwtPlot::xBottom);
        engine->setAxisAutoScale(QwtPlot::yLeft);
    }
}

bool Plotter::isLineVisible() const
{
    return lineCurve->isVisible();
}

void Plotter::setLineVisible(bool visible)
{
    lineCurve->setVisible(visible);
}

bool Plotter::isDataVisible() const
{
    return dataCurve->isVisible();
}

void Plotter::setDataVisible(bool visible)
{
    dataCurve->setVisible(visible);
}

bool Plotter::isGridVisible() const
{
    return grid->isVisible();
}

void Plotter::setGridVisible(bool visible)
{
    grid->setVisible(visible);
}

void Plotter::update(const QString& xTitle, const QVector<double> &xData, const QString& yTitle, const QVector<double> &yData)
{
    this->xData = xData;
    this->yData = yData;

    engine->setAxisTitle(QwtPlot::xBottom, xTitle);
    engine->setAxisTitle(QwtPlot::yLeft, yTitle);
    lineCurve->setSamples(xData, yData);
    dataCurve->setSamples(xData, yData);
}

void Plotter::saveImage(const QString &filepath)
{
    QwtPlotRenderer renderer;

    renderer.renderDocument(engine, filepath, QSize(200, 150));
}

void Plotter::saveData(const QString &filepath)
{
    QFile target(filepath);
    if(target.open(QFile::WriteOnly | QFile::Text))
    {
        QTextStream out(&target);
        for(int i=0; i<xData.size(); i++)
        {
            out << xData[i] << "\t" << yData[i] << endl;
        }
        target.close();
    }
}
